/**
 * *******************************************
 * user: zmq
 * describe:  定时器基类
 * created:
 * date: 2021/8/31
 * *******************************************
 */
import Utils from "../../util/utils";
import {TimeType} from "../../consts/consts";

export class BaseCron {

    private schedulerList: object = {};
    private id: number = 1;

    /**
     * 房间任务调度器，因为用cron定时队列时间100ms，所以正真的时间上存在100ms误差；
     * 减少了服务器开发过程中定时器的个数，以及提供了统一的回收机制
     */
    public scheduler() {

        let self = this;
        let schedulerList = self.schedulerList;
        let curTime = Utils.getCurTime();
        let schedulerID = 0;
        try {
            for (let id in schedulerList) { // 遍历任务进度表

                if (!schedulerList.hasOwnProperty(id)) {
                    continue;
                }

                schedulerID = Number(id);
                let schedulerObj = schedulerList[schedulerID];
                if (schedulerObj.type === TimeType.timeOut) { // 超时任务
                    if (schedulerObj.endTime <= curTime) {
                        schedulerObj.func();
                        self._remove(schedulerID);
                    }
                } else { // 步进任务
                    if (schedulerObj.endTime <= curTime) {
                        if (schedulerObj.runTime) {
                            if (schedulerObj.runTime > 0) {
                                schedulerObj.func();
                                schedulerObj.endTime += schedulerObj.intervalTime;
                            }
                            schedulerObj.runTime--;
                            if (schedulerObj.runTime <= 0) { // 运行次数耗尽
                                self._remove(schedulerID);
                            }
                        } else {
                            schedulerObj.func();
                            schedulerObj.endTime += schedulerObj.intervalTime;
                        }
                    }
                }
            }
        } catch (e) { // 异常错误要把对应的id队列删除避免后续队列被卡主不执行
            if (e) {
                throw e;
            }
            self._remove(schedulerID);
        }
    }


    /**
     * 定时任务
     * @param func
     * @param timeNum
     */
    public  timeOut (func:Function, timeNum:number) {
        let self = this;
        let id = self.id;
        let curTime = Number(Utils.getCurTime());
        self.schedulerList[id] = {
            type: TimeType.timeOut,
            func,
            endTime: timeNum + curTime,
        };
        self.id++;
        return id;
    };

    /**
     * 步进任务
     * @param func 执行回调
     * @param intervalTime 步进时间
     * @param runTime 步进次数,默认无数次
     * @returns {number}
     * @private
     */
    public interval (func:Function, intervalTime:number, runTime:number) {

        let self = this;
        let id = self.id;
        let curTime = Number(Utils.getCurTime());
        self.schedulerList[id] = {
            type: TimeType.interval,
            func,
            runTime,
            endTime: intervalTime + curTime,
            intervalTime,
        };
        self.id++;
        return id;
    };

    /**
     * 移除定时任务
     * @param id
     */
    public remove(id) {

        let self = this;
        if (!self.schedulerList[id]) {
            return;
        }

        self.schedulerList[id] = undefined;
        delete self.schedulerList[id];
    };
}
